// Copyright (c) 2025 Huawei Technologies Co., Ltd.
// openFuyao is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
//          http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.

package lm

import (
	"fmt"
	"testing"

	"github.com/agiledragon/gomonkey/v2"
)

type argsGetAcceleratorType struct {
	boardID  string
	cardNums int
}
type testParamGetAcceleratorType struct {
	name string
	args argsGetAcceleratorType
	want string
}

func genTestParamGetAcceleratorType(name string,
	boardID string, cardNums int, want string,
) testParamGetAcceleratorType {
	return testParamGetAcceleratorType{
		name: name,
		args: argsGetAcceleratorType{
			boardID:  boardID,
			cardNums: cardNums,
		},
		want: want,
	}
}

func TestGetAcceleratorType(t *testing.T) {
	cardNumSingle := 1
	cardNumHalf := 4
	cardNumModule := 8
	tests := []testParamGetAcceleratorType{
		genTestParamGetAcceleratorType(
			"half", "0x27", cardNumHalf, "half"),
		genTestParamGetAcceleratorType(
			"module", "0x27", cardNumModule, "module"),
		genTestParamGetAcceleratorType(
			"module-910b-8", "0x30", cardNumSingle, "module-910b-8"),
		genTestParamGetAcceleratorType(
			"module-910b-16", "0x51", cardNumSingle, "module-910b-16"),
		genTestParamGetAcceleratorType(
			"card", "0x01", cardNumSingle, "card"),
		genTestParamGetAcceleratorType(
			"card-910b-2", "0x10", cardNumSingle, "card-910b-2"),
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := getAcceleratorType(tt.args.boardID, tt.args.cardNums); got != tt.want {
				t.Errorf("getAcceleratorType() = %v, want %v", got, tt.want)
			}
		})
	}
}

func TestGetCardNumsAndNPUInfoCommandFail(t *testing.T) {
	patch := gomonkey.ApplyFunc(executeCommand, func(cmd string) (string, error) {
		return "", fmt.Errorf("command failed")
	})
	defer patch.Reset()
	tests := []struct {
		name               string
		want0CommandFail   int
		want1CommandFail   string
		want2CommandFail   string
		wantErrCommandFail bool
	}{
		{
			name:               "npu-smi info command failed",
			want0CommandFail:   0,
			want1CommandFail:   "",
			want2CommandFail:   "",
			wantErrCommandFail: true,
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			got, got1, got2, err := getCardNumsAndNPUInfo()
			if (err != nil) != tt.wantErrCommandFail {
				t.Errorf("getCardNumsAndNPUInfo() error = %v, wantErr %v", err, tt.wantErrCommandFail)
				return
			}
			if got != tt.want0CommandFail {
				t.Errorf("getCardNumsAndNPUInfo() got = %v, want %v", got, tt.want0CommandFail)
			}
			if got1 != tt.want1CommandFail {
				t.Errorf("getCardNumsAndNPUInfo() got1 = %v, want %v", got1, tt.want1CommandFail)
			}
			if got2 != tt.want2CommandFail {
				t.Errorf("getCardNumsAndNPUInfo() got2 = %v, want %v", got2, tt.want2CommandFail)
			}
		})
	}
}

func TestGetCardNumsAndNPUInfoCommandSuccess(t *testing.T) {
	patch := gomonkey.ApplyFunc(executeCommand, func(cmd string) (string, error) {
		return `NPU ID Chip ID Chip Logic ID Chip Name
 0 0 0 Ascend 310B1
 0 1 - Mcu`, nil
	})
	defer patch.Reset()
	tests := []struct {
		name                  string
		want0CommandSuccess   int
		want1CommandSuccess   string
		want2CommandSuccess   string
		wantErrCommandSuccess bool
	}{
		{
			name:                  "npu-smi info command succeed",
			want0CommandSuccess:   1,
			want1CommandSuccess:   "0",
			want2CommandSuccess:   "0",
			wantErrCommandSuccess: false,
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			got, got1, got2, err := getCardNumsAndNPUInfo()
			if (err != nil) != tt.wantErrCommandSuccess {
				t.Errorf("getCardNumsAndNPUInfo() error = %v, wantErr %v", err, tt.wantErrCommandSuccess)
				return
			}
			if got != tt.want0CommandSuccess {
				t.Errorf("getCardNumsAndNPUInfo() got = %v, want %v", got, tt.want0CommandSuccess)
			}
			if got1 != tt.want1CommandSuccess {
				t.Errorf("getCardNumsAndNPUInfo() got1 = %v, want %v", got1, tt.want1CommandSuccess)
			}
			if got2 != tt.want2CommandSuccess {
				t.Errorf("getCardNumsAndNPUInfo() got2 = %v, want %v", got2, tt.want2CommandSuccess)
			}
		})
	}
}
